<script setup lang="ts">
import { computed, onBeforeUnmount, onMounted, provide, ref, watchEffect } from 'vue'
import { Fold, Expand, Location } from '@/util/icons'
import { useUserStore } from '@/stores'
import RecursiveMenu from './RecursiveMenu.vue'
import { useRoute, useRouter } from 'vue-router'
import type { WindowTag } from '@/types/menu'
import { searchMatched } from '@/util/menu'
import type { ComponentSize } from 'element-plus'
// import type AsyncComponent from './AsyncComponent.vue'
import zhCn from 'element-plus/dist/locale/zh-cn.mjs'
import en from 'element-plus/dist/locale/en.mjs'
import { useConfigStore } from '@/stores/config'
const isCollapse = ref(false)
const userStore = useUserStore()
const router = useRouter()
const route = useRoute()
// 窗口标签管理器数据
const windowTags = ref<WindowTag[]>([])
// 添加窗口管理器标签
function pushTag(tag: WindowTag) {
  if (tag.value === 'home') {
    return
  }
  for (let t of windowTags.value) {
    if (t.value === tag.value) {
      return
    }
  }
  windowTags.value.push(tag)
}
// 关闭标签
function closeTag(tag: WindowTag) {
  // cache
  let tags = windowTags.value
  tags.splice(windowTags.value.indexOf(tag), 1)
  if (tags.length > 0) {
    // 关闭逻辑
    if (route.name == tag.value) {
      router.push({ name: tags[tags.length - 1].value })
    }
  } else {
    router.push({ name: 'home' })
  }
}
// 提供给子组件 添加窗口管理
provide('pushTag', pushTag)
onMounted(() => {
  pushTag({
    label: route.meta.name! as string,
    value: route.name as string
  })
})

const configSize = ref<ComponentSize>('small')

// 菜单容器dom
const navLeft = ref<HTMLElement>()
const navLeftWitdh = ref(0)
// 控制主容器大小
let resOb = new ResizeObserver(() => {
  navLeftWitdh.value = navLeft.value?.offsetWidth || 100
})

// 抽屉控制
const drawer = ref(false)
/**
 * 控制屏幕最初是否需要菜单收起
 */
function barControl() {
  if (window.innerWidth < 1200) {
    isCollapse.value = true
  }
  if (window.innerWidth <= 768) {
    drawer.value = true
  } else {
    drawer.value = false
  }
}

onMounted(() => {
  barControl()
  resOb.observe(navLeft.value!)
})
/**
 * 监听视口大小变化
 */
onresize = () => {
  barControl()
}

// 窗口归位关闭所有窗口 回到用户主页
function clearWindow() {
  windowTags.value = []
  router.replace({ name: 'home' })
}
defineExpose({
  clearWindow,
  pushTag,
  closeTag
})
watchEffect(() => {
  router.afterEach(() => {
    pushTag({
      value: route.name as string,
      label: route.meta.name as string
    })
  })
})
// 国际化
const language = ref('zh-cn')
const locale = computed(() => (language.value === 'zh-cn' ? zhCn : en))

const config = useConfigStore()
onBeforeUnmount(() => {
  onload = () => {}
})
</script>
<template>
  <el-config-provider :size="configSize" :locale="locale">
    <div class="nav-ctx" :style="{ '--menu-width': navLeftWitdh + 'px' }">
      <div class="nav-left" v-if="!drawer" ref="navLeft">
        <h2 class="sys-title" v-if="!isCollapse">{{ config.data.get('##sysName')?.value }}</h2>
        <h2 class="sys-icon" v-else></h2>
        <el-scrollbar>
          <el-menu :default-active="route.name" :collapse="isCollapse" :unique-opened="true">
            <RecursiveMenu v-for="m in userStore.menus" :route-data="m" :key="m.name" />
          </el-menu>
        </el-scrollbar>
      </div>
      <!-- 抽屉导航栏 -->
      <el-drawer
        v-else
        :modelValue="!isCollapse"
        @close="isCollapse = true"
        :title="config.data.get('##sysName')?.value"
        direction="ltr"
      >
        <el-scrollbar>
          <el-menu v-once :default-active="route.name" :unique-opened="true">
            <RecursiveMenu v-for="m in userStore.menus" :route-data="m" :key="m.name" />
          </el-menu>
        </el-scrollbar>
      </el-drawer>
      <div class="nav-content">
        <div class="nav-top">
          <div class="user-info-bar">
            <el-icon class="spread-button" @click="isCollapse = !isCollapse">
              <Expand v-if="isCollapse" />
              <Fold v-else />
            </el-icon>
            <div>
              <el-breadcrumb>
                <el-breadcrumb-item :to="{ name: 'home' }">首页</el-breadcrumb-item>
                <el-breadcrumb-item
                  class="breadcrumb-orther"
                  v-for="ro in searchMatched(route.name! as string)"
                >
                  {{ ro.name }}
                </el-breadcrumb-item>
              </el-breadcrumb>
            </div>
            <div class="user-header">
              <slot name="head"></slot>
            </div>
          </div>
          <div class="window-manage-box">
            <el-tag
              @click="router.push({ name: 'home' })"
              :type="route.name == 'home' ? 'success' : ''"
              :effect="route.name == 'home' ? 'dark' : 'light'"
              ><el-icon v-if="route.name == 'home'">
                <Location />
              </el-icon>
              首页</el-tag
            >
            <el-tag
              v-for="tag in windowTags"
              :key="tag.label"
              @click="router.push({ name: tag.value })"
              @close="closeTag(tag)"
              closable
              :type="route.name == tag.value ? 'success' : ''"
              :effect="route.name == tag.value ? 'dark' : 'light'"
              ><el-icon v-if="route.name == tag.value">
                <Location /> </el-icon
              >{{ tag.label }}</el-tag
            >
          </div>
        </div>
        <div class="nav-router-view">
          <RouterView #default="{ Component, route }">
            <Transition name="router">
              <slot v-if="route.name == 'home'"> </slot>
              <!-- <AsyncComponent v-else :path="route.meta.comPath"></AsyncComponent> -->
              <KeepAlive v-else :max="5">
                <component :is="Component"></component>
              </KeepAlive>
            </Transition>
          </RouterView>
        </div>
      </div>
    </div>
  </el-config-provider>
</template>
<style>
.router-enter-active {
  transition: all 0.3s;
  transition-delay: 0.3s;
  opacity: 1;
}

.router-enter-from,
.router-leave-to {
  transition: all 0.3s;
  opacity: 0;
}

.router-enter-from {
  transform: translateX(-50px);
}

.router-leave-to {
  transform: translateX(50px);
}
</style>
<style lang="less" scoped>
@title-height: 40px;
@nav-width: 200px;

.nav-ctx {
  height: 100%;
  width: 100%;
  display: flex;
  overflow: hidden;
}

.nav-content {
  height: 100%;
  width: calc(100% - var(--menu-width));
  box-sizing: border-box;

  @media (max-width: 768px) {
    width: 100%;
  }
}

.nav-left {
  border-right: solid 1px var(--el-menu-border-color);

  .sys-title {
    text-align: center;
    width: @nav-width;
    height: @title-height;
    line-height: @title-height;
  }

  .el-scrollbar {
    height: calc(100% - @title-height);
  }

  .el-menu {
    user-select: none;
    border: none;
  }
}

.nav-ctx :deep(.el-drawer) {
  min-width: 200px;
  width: 50vw !important;

  .el-scrollbar {
    width: 100%;
  }

  .el-menu,
  .el-menu-item,
  .el-sub-menu {
    max-width: none;
    width: 100%;
  }

  .el-drawer__body {
    padding: 0;
  }
}

// 用户信息栏高度
@nav-top-height: 80px;
// 移动端高度
@nav-top-model-height: 60px;

.nav-content {
  overflow: hidden;

  .nav-top {
    height: @nav-top-height;

    @media (max-width: 600px) {
      height: @nav-top-model-height;
    }

    box-sizing: border-box;
    box-shadow: 0 -1px 3px gray;
  }

  @user-info-bar-height: 60%;

  .user-info-bar {
    height: @user-info-bar-height;
    box-sizing: border-box;

    @media (max-width: 600px) {
      height: 100%;
    }
  }

  .window-manage-box {
    box-sizing: border-box;
    border-bottom: 1px gainsboro solid;
    display: flex;
    align-items: center;
    justify-content: flex-start;
    padding: 0px 10px;
    height: calc(100% - @user-info-bar-height);

    // 小屏 隐藏
    @media (max-width: 600px) {
      display: none;
    }

    .el-tag {
      cursor: pointer;
      height: 80%;
      margin-left: 3px;
    }
  }
}

// 用户信息条
.user-info-bar {
  user-select: none;
  display: flex;
  align-items: center;
  padding: 0px 10px;
  position: relative;

  // 菜单折叠按钮
  .spread-button {
    font-size: 20px;
    cursor: pointer;
  }

  // 面包屑导航
  .el-breadcrumb {
    margin-left: 20px;
  }

  .breadcrumb-orther {
    @media (max-width: 600px) {
      display: none;
    }
  }

  .user-header {
    position: absolute;
    right: 10px;
    height: 100%;
  }
}

/* 路由页面详情 */

.nav-router-view {
  height: calc(100% - @nav-top-height);
  width: 100%;
  overflow: hidden;

  @media (max-width: 600px) {
    height: calc(100% - @nav-top-model-height);
  }
}
</style>
